#include "bitinput.hpp"
#include <cstring>

namespace fur
{
   BitInputBase::BitInputBase(size_t buffsize) throw(Exception)
   try
   {
      data = new uint8_t[buffsize + 2];
      bitposi = byteposi = 0;
      maxsize = size = buffsize;
   }
   catch (std::bad_alloc)
   {
      throw EAllocation(__func__);
   }
   
   BitInputBase::BitInputBase(uint8_t *array, size_t buffsize) throw(Exception)
   try
   {
	 data = new uint8_t[buffsize + 2];
      bitposi = byteposi = 0;
      maxsize = size = buffsize;
      memcpy(data, array, size);
   }
   catch (std::bad_alloc)
   {
      throw EAllocation(__func__);
   }

   BitInputBase::~BitInputBase() throw()
   {
      delete [] data;
   }
   
   void BitInputBase::align() throw()
   {
      if ( bitposi != 0 )
      {
	 ++byteposi;
	 bitposi = 0;
      }
   }

   void BitInputBase::reset() throw()
   {
      bitposi = 0;
      byteposi = 0;
   }

   BitInput::BitInput(std::istream &file, size_t buffsize) throw(Exception)
 :BitInputBase(buffsize), is(file)
   {
      size = 0;
   }

   BitInput::~BitInput() throw()
   {
   }

   bool BitInput::read() throw()
   {
      if (byteposi > size / 2)
      {
	 memmove(data, data + byteposi, size - byteposi);
	 size -= byteposi;
	 byteposi = 0;
      }
      is.read(reinterpret_cast<char*>(data + size), maxsize - size);
      size += is.gcount();
      return (is.gcount() != 0);
   }
   
   bool BitInput::eof() throw()
   {
      return (byteposi == size) && is.eof();
   }
   
} // end of namespace fur
